/// <reference path="../typings/index.d.ts" />
import * as msgdefine from "./msgdefine"
import userbot from "./userbot"

interface msgHandle {
    process(data: any): void;
}
export default class botMgr {
    private id = ""
    private socket: SocketIOClient.Socket;
    private msgHandle: Map<msgdefine.MsgType, msgHandle> = new Map();
    private heartTimer: any = null;
    private gameTimer: any = null;
    private userMap: Map<string, userbot> = new Map();
    private requestRooms: Map<number, {
        group_id: string;
        user: string;
        gameType: string;
        roomId: number;
    }> = new Map();
    constructor(_id: string, linkaddress: string) {
        this.msgHandle.set(msgdefine.MsgType.sc_login, { process: this.sc_login });
        this.msgHandle.set(msgdefine.MsgType.sc_groupconfig, { process: this.sc_groupconfig });
        this.msgHandle.set(msgdefine.MsgType.sc_contactgroups, { process: this.sc_contactgroups });
        this.msgHandle.set(msgdefine.MsgType.sc_creategame, { process: this.sc_creategame });

        this.msgHandle.set(msgdefine.MsgType.sc_gameinfo, { process: this.sc_gameinfo });

        this.msgHandle.set(msgdefine.MsgType.sc_configgroup, { process: this.sc_configgroup });
        this.msgHandle.set(msgdefine.MsgType.sc_deleteroom, { process: this.sc_deleteroom });
        this.msgHandle.set(msgdefine.MsgType.sc_loginout, { process: this.sc_loginout });
        this.msgHandle.set(msgdefine.MsgType.sc_new, { process: this.sc_new });
        this.msgHandle.set(msgdefine.MsgType.sc_grouppause, { process: this.sc_grouppause });
        this.msgHandle.set(msgdefine.MsgType.sc_broadcast, { process: this.sc_broadcast });
        this.id = _id;
        this.socket = require('socket.io-client')(linkaddress);
        this.socket.on("connect", () => {
            console.log("connected");
            this.socket.emit("login", {
                id: this.id
            });

            this.heartTimer = setInterval(() => {
                this.heart();

            }, 1000);
            this.gameTimer = setInterval(() => {
                console.log("now clients:" + this.userMap.size)
                this.cs_gameinfo();
            }, 10000);
        });
        this.socket.on("disconnect", () => {
            clearInterval(this.heartTimer);
            clearInterval(this.gameTimer);
            this.requestRooms.clear();
        })
        this.socket.on("message", (data) => {
            this.onMessage(data)
        });

    }
    private heart() {
        let users: string[] = []
        for (let u of this.userMap.keys()) {
            users.push(u);
        }
        this.socket.emit("heart", {
            id: this.id,
            body: users
        });
    }
    private sendMessage(data: msgdefine.msgpack) {

        this.socket.emit("message", {
            id: this.id,
            body: data
        });
    }
    public onMessage(data: msgdefine.msgpack) {
        let handle = this.msgHandle.get(data.type);
        if (handle) {
            if (data.type != msgdefine.MsgType.sc_gameinfo)
            { console.log("recved:" + data.type + handle.process.name) }
            handle.process.call(this, data.content);
        }
    }
    private sc_login(data: msgdefine.i_sc_login) {
        if (this.userMap.has(data.user)) {
            return;
        }
        let u = new userbot(this, data.user, data.snykey);
        this.userMap.set(data.user, u);
    }
    private sc_groupconfig(data: msgdefine.i_sc_groupconfig) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_groupconfig(data);
        }
    }
    private sc_contactgroups(data: msgdefine.i_sc_contactgroups) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_contactgroups(data);
        }
    }
    private sc_creategame(data: msgdefine.i_sc_creategame) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_creategame(data);
        }
    }
    private sc_gameinfo(data: msgdefine.i_sc_gameinfo) {
        data.rooms.forEach(room => {
            let u: userbot = this.userMap.get(room.user);
            if (u) {
                u.sc_gameinfo(room);
            }
        })

    }
    private sc_configgroup(data: msgdefine.i_sc_configgroup) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_configgroup(data);
        }
    }
    private sc_deleteroom(data: msgdefine.i_sc_deleteroom) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_deleteroom(data);
        }
    }
    private sc_loginout(data: msgdefine.i_sc_loginout) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_loginout(data);
            this.userMap.delete(data.user);
        }
    }
    private sc_new(data: msgdefine.i_sc_new) {
        if (this.userMap.has(data.user)) {
            return;
        }
        new userbot(this, data.user, null);

    }
    private sc_grouppause(data: msgdefine.i_sc_grouppause) {
        let u: userbot = this.userMap.get(data.user);
        if (u) {
            u.sc_grouppause(data);
        }
    }
    private sc_broadcast(data: msgdefine.i_sc_broadcast) {
        for (let [key, user] of this.userMap.entries()) {
            let isFind = data.whitelist.findIndex((white) => {
                if (white.whiteType == msgdefine.WhiteType.user && white.keyword == key) return true;
                return false;
            })
            if (isFind != -1) continue;
            user.sc_broadcast(data);
        }
    }
    //
    public loginOk(user: string, bot: userbot) {
        this.userMap.set(user, bot);
    }
    public cs_login(data: msgdefine.i_cs_login) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_login,
            content: data
        });
    }
    public cs_getgroupconfig(data: msgdefine.i_cs_getgroupconfig) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_getgroupconfig,
            content: data
        });
    }
    public cs_contactgroups(data: msgdefine.i_cs_contactgroups) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_contactgroups,
            content: data
        });
    }
    public cs_creategame(data: msgdefine.i_cs_creategame) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_creategame,
            content: data
        });
    }
    public requestRoomRefash(room: {
        group_id: string;
        user: string;
        gameType: string;
        roomId: number;
    }) {
        this.requestRooms.set(room.roomId, room);
    }
    private cs_gameinfo() {
        //把缓存中所有的rooms取出
        if (this.requestRooms.size <= 0) return;
        let data: msgdefine.i_cs_gameinfo = {
            rooms: []
        };
        for (let v of this.requestRooms.values()) {
            data.rooms.push(v);
        }
        this.requestRooms.clear();
        this.sendMessage({
            type: msgdefine.MsgType.cs_gameinfo,
            content: data
        });
    }
    public cs_leavegroup(data: msgdefine.i_cs_leavegroup) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_leavegroup,
            content: data
        });
    }
    public cs_invitegroup(data: msgdefine.i_cs_invitegroup) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_invitegroup,
            content: data
        });
    }
    public cs_configgroup(data: msgdefine.i_cs_configgroup) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_configgroup,
            content: data
        });
    }
    public cs_loginout(data: msgdefine.i_cs_loginout) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_loginout,
            content: data
        });
        this.userMap.delete(data.user);
    }
    public cs_new(data: msgdefine.i_cs_new) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_new,
            content: data
        })
    }
    public cs_groupnamechange(data: msgdefine.i_cs_groupnamechange) {
        this.sendMessage({
            type: msgdefine.MsgType.cs_groupnamechange,
            content: data
        })
    }
}